#!/usr/bin/perl -w
#
#	$Id$
#
#
# genmibsrc - generate C source file to register MIB nodes from a MIB
#             definitions file
#
#

use strict;

use Getopt::Std;
use Data::Dumper;


$0 =~ /([^\/]*)$/;
my $progname = $1;


my $infile;
my $outfile = 'mibdef.c';
my $funcname = 'register_mib_defs';
my $logchansymbol = 'logchan';
my $mibsymbol = 'mib';

my $mib_version = undef;

exit(main());




########################################################################
# main - function
########################################################################

sub main
{
	parse_argv();

	$infile = shift(@ARGV);

	open(MIBDEF, $infile) || die "Failed to open $infile: $!\n";
	open(CSRC, ">$outfile") || die "Failed to open $outfile: $!\n";

	write_header(\*CSRC);

	my $path;
	my $type;
	my $mode;

	my $lineno = 0;
	while (<MIBDEF>) {
		$lineno++;
		next if ($_ =~ /^#/);
		next if ($_ =~ /^\s+$/);

		if ($_ =~ /^!(\w+)\s*(.*)$/) {
			my $line = $2;
			if ($1 eq 'version') {
				if ($line =~ /^(\d+)$/) {
					$mib_version = $1;
				} else {
				}
			} elsif ($1 eq 'outfile') {
			}

			next;
		}

		if (!($_ =~ /^(\S+)\s+(\S+)\s+(\S+)/)) {
			print STDERR "${infile}[$lineno]: syntax error\n";
		}

		$path = $1;
		$type = $2;
		$mode = $3;

		if ($path !~ /^[A-Za-z0-9._]+$/) {
			print STDERR "${infile}[$lineno]: invalid characters in MIB path `$path'\n";
			return (1);
		}

		if ($type eq 'branch') {
			$type = 'CNP_MIB_TYPE_BRANCH';
		} elsif ($type eq 'string') {
			$type = 'CNP_MIB_TYPE_STRING';
		} elsif ($type eq 'bool') {
			$type = 'CNP_MIB_TYPE_BOOL';
		} elsif ($type eq 'int') {
			$type = 'CNP_MIB_TYPE_INT';
		} else {
			print STDERR "${infile}[$lineno]: invalid MIB node type `$type'\n";
			return (1);
		}

		if ($mode eq 'ro') {
			$mode = 'CNP_MIB_MODE_RO';
		} elsif ($mode eq 'rw') {
			$mode = 'CNP_MIB_MODE_RW';
		} else {
			print STDERR "${infile}[$lineno]: invalid MIB access mode `$mode'\n";
			return (1);
		}

		print CSRC <<EOC;

	ret = cnp_mib_mknode($mibsymbol, "$path",
	    $type, $mode, 0);
	if (ret == -1) {
		cnp_log($logchansymbol, CNP_LOG_ERR,
		    "failed to register MIB node `$path'");
		return (-1);
	}
EOC

	}

	write_footer(\*CSRC);

	close(MIBDEF);
	close(CSRC);

	return (0);
}

########################################################################
# parse_argv - function
########################################################################

sub parse_argv
{
	my %opts;

	getopts('f:hl:m:o:', \%opts);

	if (defined($opts{h})) {
		usage();
		exit(0);
	}

	if (defined($opts{f})) {
		$funcname = $opts{f};
	}

	if (defined($opts{l})) {
		$logchansymbol = $opts{l};
	}

	if (defined($opts{m})) {
		$mibsymbol = $opts{m};
	}

	if (defined($opts{o})) {
		$outfile = $opts{o};
	}
}

########################################################################
# usage - function
########################################################################

sub usage
{
	my $progname = $0;
	$progname =~ s/([^\/]*)$/$1/;

	print STDERR <<EOU;
Usage: $progname [-hr] [-f symbol] [-l symbol] [-m symbol] [-o file] file
	-f symbol	Use <symbol> for the name of the generated function
	-h		Display usage information and exit
	-l symbol	Use <symbol> for the name of the log channel
	-m symbol	Use <symbol> for the name of the MIB object
	-o file		Use <file> as the name of the output file
EOU
}

########################################################################
# write_header - function
########################################################################

sub write_header
{
	my $fh = shift();
	my $date = localtime(time());

	print $fh <<EOH;
/*
 * $outfile
 *
 * This file was autogenerated by the $progname script from the source file
 * $infile on $date.
 */

#include <sys/types.h>

#include <stdio.h>

#include <canopy/log.h>
#include <canopy/mib.h>


extern cnp_mib_t *$mibsymbol;
extern cnp_log_t *$logchansymbol;



int  $funcname  (void);



int
$funcname(void)
{
	int ret = 0;

EOH


}


########################################################################
# write_footer - function
########################################################################

sub write_footer
{
	my $fh = shift();

	print $fh <<EOC;

	return (ret);
}
EOC
}
